<template>
  <div>
    <div class="flx-b">
      <div id="container"></div>
      <div id="map"></div>
    </div>

    <ZgButton class="mr10" @click="exportData()">导出数据</ZgButton>
    <ZgButton class="mr10" @click="importData()">导入数据</ZgButton>
    <ZgButton class="mr10" @click="addNode()">添加节点</ZgButton>
    <ZgButton class="mr10" @click="addEdge()">连线</ZgButton>
    <ZgButton class="mr10" @click="addVerticesEdge()">添加路径点连线</ZgButton>
    <div class="flx-s mt10">
      <ZgButton class="mr10" @click="addVerticesRouterEdge()">添加router连线</ZgButton>
      <ZgSelect :modelVal="defautRouter" class="mr10 w100" :options="routerOptions" @change="changeRouter"></ZgSelect>
    </div>
    <div class="flx-s mt10">
      <ZgButton class="mr10" @click="addConnectorEdge()">添加连接器连线</ZgButton>
      <ZgSelect :modelVal="defautConnector" class="mr10 w100" :options="connectorOptions" @change="changeConnector"></ZgSelect>
    </div>
    <div id="laneDiagram"></div>

  </div>

</template>
<script>
import { data, testData, LaneDiagramData } from './data.js'
// LaneDiagramData   data1
import { Graph } from '@antv/x6'

export default {

  data () {
    return {
      graph: '',
      map: '',
      laneDiagram: '',
      routerOptions: [
        { label: 'normal', value: 'normal' },
        { label: 'orth', value: 'orth' },
        { label: 'oneSide', value: 'oneSide' },
        { label: 'manhattan', value: 'manhattan' },
        { label: 'metro', value: 'metro' },
        { label: 'er', value: 'er' }
      ],
      defautRouter: 'normal',
      connectorOptions: [
        { label: 'normal', value: 'normal' },
        { label: 'rounded', value: 'rounded' },
        { label: 'smooth', value: 'smooth' },
        { label: 'jumpover', value: 'jumpover' }

      ],
      defautConnector: 'normal',
      maxLevel: 1
    }
  },
  methods: {
    exportData () {
      const dataJson = this.graph.toJSON()
      sessionStorage.setItem('x6-data', JSON.stringify(dataJson))
      alert(JSON.stringify(dataJson))
    },
    importData () {
      const dataJson = sessionStorage.getItem('x6-data')
      if (dataJson) {
        this.map.fromJSON(JSON.parse(dataJson))
        this.map.centerContent() // 居中显示
      }
    },
    addNode () {
      const commonAttrs = {
        body: {
          fill: '#fff',
          stroke: '#8f8f8f',
          strokeWidth: 1
        },
        label: {
          refX: 0.5,
          refY: '100%',
          refY2: 4,
          textAnchor: 'middle',
          textVerticalAnchor: 'top'
        }
      }
      this.graph.addNode({
        id: 'node5',
        shape: 'ellipse',
        x: 280,
        y: 40,
        width: 80,
        height: 40,
        label: 'ellipse',
        attrs: commonAttrs
      })
    },
    addEdge () {
      this.graph.addEdge({
        source: 'node3',
        target: 'node4',
        attrs: {
          line: {
            stroke: '#8f8f8f',
            strokeWidth: 1
          }
        }
      })
    },
    addVerticesEdge () {
      this.graph.addEdge({
        source: 'node4',
        target: 'node5',
        vertices: [
          { x: -100, y: 100 },
          { x: 200, y: 100 }
        ],
        attrs: {
          line: {
            stroke: '#8f8f8f',
            strokeWidth: 1
          }
        }
      })
    },
    addVerticesRouterEdge () {
      this.graph.addEdge({
        source: 'node4',
        target: 'node5',
        vertices: [
          { x: -100, y: 100 },
          { x: 200, y: 100 }
        ],
        attrs: {
          line: {
            stroke: '#8f8f8f',
            strokeWidth: 1
          }
        },
        // 如果没有 args 参数，可以简写为 router: 'orth'
        router: {
          name: this.defautRouter, // 默认值是 'normal' orth manhattan oneSide metron er
          args: {}
        }
      })
    },
    changeRouter (value) {
      console.log(value)
      this.defautRouter = value
    },
    addConnectorEdge () {
      this.graph.addEdge({
        source: 'node4',
        target: 'node5',
        vertices: [
          { x: -100, y: 100 },
          { x: 200, y: 100 }
        ],
        attrs: {
          line: {
            stroke: '#8f8f8f',
            strokeWidth: 1
          }
        },
        // 如果没有 args 参数，可以简写为 router: 'orth'
        router: {
          name: this.defautRouter, // 默认值是 'normal' orth manhattan oneSide metron er
          args: {}
        },
        // 如果没有 args 参数，可以简写写 connector: 'rounded'
        connector: {
          name: this.defautConnector,
          args: {}
        }
      })
    },
    changeConnector (value) {
       console.log(value)
      this.defautConnector = value
    },
    cellClick ({ view, cell }) {
      alert('点击了节点/边元素')
    },
    nodeClick ({ e, x, y, node, view }) {
        alert('点击了节点元素')

      console.log('node', node)
      console.log('e', e)
      console.log('view', view)
      console.log('x', x, y)
    },
    portClick ({ e, x, y, port, view }) {
      console.log('port', port)
      console.log('e', e)
      console.log('view', view)
      console.log('x', x, y)
    },
    edgeClick ({ e, x, y, edge, view }) {
      alert('点击了边元素')
    },
    init () {
      if (!this.graph) {
        this.graph = new Graph({
          container: document.getElementById('container'),
          width: 600,
          height: 600,
          background: {
            color: '#F2F7FA'
          }
        })
        this.graph.fromJSON(data) // 渲染元素
        this.graph.centerContent() // 居中显示

        // this.graph.on('cell:click', this.cellClick)
        this.graph.on('node:click', this.nodeClick)
        this.graph.on('node:port:click', this.portClick)
        this.graph.on('edge:click', this.edgeClick)

        this.graph.on('blank:click', ({ e, x, y }) => {
          alert('点击了空白处')
        })
      }
      if (!this.map) {
        this.map = new Graph({
          container: document.getElementById('map'),
          width: 600,
          height: 600,
          background: {
            color: '#ccc'
          }
        })
        this.map.centerContent() // 居中显示
      }
    },
    initLaneDiagram (data) {
      if (!this.laneDiagram) {
        Graph.registerNode(
          'lane',
          {
            inherit: 'rect',
            markup: [
              {
                tagName: 'rect',
                selector: 'body'
              },
              {
                tagName: 'rect',
                selector: 'name-rect'
              },
              {
                tagName: 'text',
                selector: 'name-text'
              }
            ],
            attrs: {
              body: {
                fill: '#FFF',
                stroke: '#5F95FF',
                strokeWidth: 1
              },
              'name-rect': {
                width: 200,
                height: 30,
                fill: '#5F95FF',
                stroke: '#fff',
                strokeWidth: 1,
                x: -1
              },
              'name-text': {
                ref: 'name-rect',
                refY: 0.5,
                refX: 0.5,
                textAnchor: 'middle',
                fontWeight: 'bold',
                fill: '#fff',
                fontSize: 12
              }
            }
          },
          true
        )

        Graph.registerNode(
          'lane-rect',
          {
            inherit: 'rect',
            width: 100,
            height: 60,
            attrs: {
              body: {
                strokeWidth: 1,
                stroke: '#5F95FF',
                fill: '#EFF4FF'
              },
              text: {
                fontSize: 12,
                fill: '#262626'
              }
            }
          },
          true
        )

        Graph.registerNode(
          'lane-polygon',
          {
            inherit: 'polygon',
            width: 80,
            height: 80,
            attrs: {
              body: {
                strokeWidth: 1,
                stroke: '#5F95FF',
                fill: '#EFF4FF',
                refPoints: '0,10 10,0 20,10 10,20'
              },
              text: {
                fontSize: 12,
                fill: '#262626'
              }
            }
          },
          true
        )

        Graph.registerEdge(
          'lane-edge',
          {
            inherit: 'edge',
            attrs: {
              line: {
                stroke: '#A2B1C3',
                strokeWidth: 2
              }
            },
            label: {
              attrs: {
                label: {
                  fill: '#A2B1C3',
                  fontSize: 12
                }
              }
            }
          },
          true
        )
        const that = this
        this.laneDiagram = new Graph({
          container: document.getElementById('laneDiagram'),
          width: 1300,
          height: 600,
          connecting: {
            router: 'orth'
          },
          translating: {
            restrict (cellView) {
              const cell = cellView.cell
              const parentId = cell.prop('parent')
              if (parentId) {
                const parentNode = that.laneDiagram.getCellById(parentId)
                if (parentNode) {
                  return parentNode.getBBox().moveAndExpand({
                    x: 0,
                    y: 30,
                    width: 0,
                    height: -30
                  })
                }
              }
              return cell.getBBox()
            }
          }
        })
        const cells = []
        // data1.forEach((item) => {
        LaneDiagramData.forEach((item) => {
        // data.forEach((item) => {
          if (item.shape === 'lane-edge') {
            cells.push(this.laneDiagram.createEdge(item))
          } else {
            cells.push(this.laneDiagram.createNode(item))
          }
        })
        this.laneDiagram.resetCells(cells)
        this.laneDiagram.zoomToFit({ padding: 10, maxScale: 1 })
      }
    },
    setData (arr) {
      const edgeArr = []
      const nodeArr = []
      const flat = 1
      const that = this
      function recurse (arr, flat, parentId) {
        for (let i = 0; i < arr.length; i++) {
          if (parentId) {
            edgeArr.push({
              id: 'lane-edge-' + arr[i].id + '-' + parentId,
              'shape': 'lane-edge',
              source: parentId,
              target: arr[i].id,
              label: arr[i].label
            })
          }
          that.maxLevel = flat > that.maxLevel ? flat : that.maxLevel
          const labelObj = {

            x: 40 + i * 100,
            y: 40 + flat * 200,
            width: 100,
            height: 40,
            attrs: {
              // body 是选择器名称，选中的是 rect 元素
              body: {
                stroke: '#8f8f8f',
                strokeWidth: 1,
                fill: '#fff',
                rx: 6,
                ry: 6
              }
            },
            parent: flat
          }
          nodeArr.push(Object.assign({}, arr[i], labelObj))
          if (Array.isArray(arr[i].children)) {
              recurse(arr[i].children, flat + 1, arr[i].id)
          }
        }
      }
      recurse(arr, flat)
      const data = nodeArr.concat(edgeArr)
      return data
    },
    laneSet (data) {
      const laneArr = []
      for (let i = 0; i < this.maxLevel; i++) {
        laneArr.push({
          'id': i + 1,
          'shape': 'lane',
          'width': 800,
          'height': 200,
          'position': {
            'x': 60,
            'y': 60 + i * 200
          },
          'label': '第' + (i + 1) + '道'
        })
      }
      const allData = laneArr.concat(data)
      return allData
    }
  },
  mounted () {
    this.init()
    const data = this.setData(testData)
    const allData = this.laneSet(data)
    console.log('JSON.stringify(allData)', allData)
    this.initLaneDiagram(allData)
  }
}
</script>

<style lang="scss" scoped>
</style>
